#include <iostream>

using namespace std;

void defineStr()
{
    string s1;
    cout << s1 << endl; //没有赋值输出为空

    string s2(10, 'f');
    cout << s2 << endl; //用10个f定义字符串s2，输出ffffffffff

    string s3(s2);
    cout << s3 << endl; //用s2定义上，将s3拷贝给s2，s2和s3是不同的字符串，
    //只是构造的时候拷贝s2，修改其中一个不会影响另一个，s3输出位ffffffffff

    string s4(s3.begin(), s3.begin() + s3.size() / 2); //定义s4用迭代器做参数，从第一个迭代器s3.begin()
    cout << s4 << endl;                                //到第二个迭代器s3的一半即s3.size()/2结束，s3有10个f，s4输出为fffff

    char *cp = "Hello";                         //最后有空字符/0
    char c_array[] = "world!!!!";               //最后有空字符/0
    char no_null[] = {'H', 'e', 'l', 'l', '0'}; //最后没有空字符/0，不算C语言字符串，只是字符数组

    string ss1(cp);
    cout << ss1 << endl; // cp指向的字符串一个一个拷贝到ss1对象里，ssl输出为Hello

    string ss2(c_array, 5);
    cout << ss2 << endl; // c_array数组名就是指向第一个字符w的指针，从w开始取5个，ss2为world

    string ss3(c_array + 5, 4);
    cout << ss3 << endl; // c_array+5指向第五个字符d，再取4个字符，ss3为!!!!

    // string ss4(no_null);//用字符数组为ss4赋值，因为找不到/0,不知道拷贝几个会出错
    string ss5(no_null, 2); //这次取2个就知道什么时候结束，不会出错
    cout << ss5 << endl;    // ss5为He

    s1 = "Hello";
    cout << s1 << endl; // s1输出Hello

    string s6(s1, 2);
    cout << s6 << endl; //用s1初始化s6，2表示字符下标，从第二个字符开始到最后，s6为llo

    string s7(s1, 0, 2);
    cout << s7 << endl; //从s10开始取2个，s7为He

    string s8(s1, 0, 8);
    cout << s8 << endl; //从s1的第一个开始取8个，不够8个就结束，s8为Hello
}

void operStr()
{
    string s("hello");
    string s2("abcdef");

    string::iterator p = s.begin(); //迭代器p

    s.insert(p, 'A');  //在迭代器p指向的s开始之前插入A
    cout << s << endl; // s为Ahello

    s.insert(p, 3, 'B'); // p指向返回的Ahello的A处，在A之前插入3个B
    cout << s << endl;   // s为BBBAhello

    string::iterator b = s2.begin(); //迭代器b
    string::iterator e = s2.end();   //迭代器e

    // p = s.begin();       //p指向s
    s.insert(p, b, e); //在p指向的s之前插入b和e迭代器范围内的元素abcdef
    cout << s << endl; // s为abcdefBBBAhello

    s = "hello";
    cout << s << endl; // s为hello

    s.assign(b, e);    // s所有的元素倍替换为b到e之间的元素，b与e之间为s2
    cout << s << endl; // s为abcdef

    s.assign(8, 'K');
    cout << s << endl; // s为KKKKKKKK

    p = s2.begin();     //迭代器p指向s2的a
    s2.erase(p);        //删除迭代器p指向的元素a
    cout << s2 << endl; // s2为bcdef

    p = s2.begin();                 // a被删除，p指向b
    p++;                            //指向c
    p++;                            //指向d
    string::iterator p2 = s2.end(); // p2迭代器指向f
    p2--;                           //指向e
    s2.erase(p, p2);                //删除p指向的d和p2指向的e之间的元素
    cout << s2 << endl;             // s2为bcf
}

void replaceStr()
{
    string s("hello");
    string s2("abc");

    s.insert(0, 3, 'A'); //在s下标是0之前插入3个A
    cout << s << endl;   // s为AAAhello

    s.insert(5, s2);   //在AAAhello下标是5的元素之前插入abc
    cout << s << endl; // s为AAAheabcllo

    s2 = "123456";
    s.insert(0, s2, 2, 3); //在s的下标是0之前插入s2下标为2开始往后的3个元素345
    cout << s << endl;     // s为345AAAheabcllo

    char *cp = "Stately plup Buck";
    s.assign(cp, 7);
    cout << s << endl; // s为Stately

    s.assign(cp);      //没有长度，默认是拷贝全部
    cout << s << endl; // s为Stately plup Buck

    s = "hello";
    s.insert(0, cp, 7);
    cout << s << endl; // s为Statelyhello

    s.insert(0, cp);
    cout << s << endl; // s为Statelyhello

    s = "hello";
    s2 = "abcdef";

    s.assign(s2, 2, 3); // s2中下标为2开始3个元素赋值给s；
    cout << s << endl;  // s为cde

    s.assign(s2);
    cout << s << endl; // s为abcdef

    s.erase(2, 3);     //从下标为2开始删除s中的3个元素
    cout << s << endl; // s为abf

    s = "123456789";
    s.erase(s.size() - 5, 5); //删除s中后5个
    cout << s << endl;        // s为1234

    s.insert(s.size(), 5, '!'); //在s下标为s.size()处，插入5个！
    cout << s << endl;          // s为1234！！！！！

    s = "abc";
    s.erase(0, 1).insert(0, "A"); //先从下标为0之前删除一个a为bc，再插入A
    cout << s << endl;            // s为Abc

    s = "abc";
    s[0] = 'A';        //用数组的方式处理
    cout << s << endl; // s为Abc
}

void subStr()
{
    string s("Hello world");
    string s2 = s.substr(6, 5); //从第6个开始取5个
    cout << s2 << endl;         // s2为world

    s2 = s.substr(6);   //从第6个开始取拷贝所有的
    cout << s2 << endl; // s2为world

    s2 = s.substr(6);   // s2拷贝s的全部，相当于s2=s
    cout << s2 << endl; // s2为Hello world

    s = "C++ Primer";
    s.append(" 3rd Ed"); //再s最后添加3rd Ed
    cout << s << endl;   // s为C++ Primer 3rd Ed

    s = "C++ Primer";
    s.insert(s.size(), " 3rd Ed"); //最后插入
    cout << s << endl;             // s为C++ Primer 3rd Ed

    s.replace(11, 3, "4th"); //下标11开始3个替换4th
    cout << s << endl;       // s为C++ Primer 4th Ed

    s.replace(11, 3, "Fourth"); //下标11开始3个替换Fourth
    cout << s << endl;          // s为C++ Primer Fourth Ed

    s = "C++ Primer 3rd Ed"; // replace相当于先删除后插入
    s.erase(11, 3);          //删除3rd
    s.insert(11, "Fourth");  //插入Fourth
    cout << s << endl;       // s为C++ Primer Fourth Ed
}

/*

string类型的查找
s.find( args);              //在 s 中查找 args 的第一次出现
s.rfind( args)                   // 在 s 中查找 args 的最后一次出现
s.find_first_of( args)      //在 s 中查找 args 的任意字符的第一次出现
s.find_last_of( args)          //在 s 中查找 args 的任意字符的最后一次出现
s.find_first_not_of( args)       //在 s 中查找第一个不属于 args 的字符
s.find_last_not_of( args)          //在 s 中查找最后一个不属于 args 的字符
*/

int main(int argc, char **argv)
{
    defineStr();

    return 0;
}
